package com.guqj.nio.netty.pstack.util;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.guqj.nio.netty.pstack.pojo.Header;
import com.guqj.nio.netty.pstack.pojo.NettyMessage;

public class NettyMessageDecoder extends LengthFieldBasedFrameDecoder {

	private NettyMarshallingDecoder nettyMarshallingDecoder;

	public NettyMessageDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip) throws IOException {
		super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip);
		nettyMarshallingDecoder = new NettyMarshallingDecoder();
	}

	@Override
	protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
		ByteBuf inBuf = (ByteBuf) super.decode(ctx, in);
		if (inBuf == null) {
			return null;
		}
		NettyMessage message = new NettyMessage();
		Header header = new Header();
		header.setCrcCode(in.readInt());
		header.setLength(in.readInt());
		header.setSessionID(nettyMarshallingDecoder.decode(in).toString());
		header.setType(in.readByte());
		header.setPriority(in.readByte());
		message.setHeader(header);

		int size = in.readInt();

		if (size > 0) {
			Map<String, Object> attach = new HashMap<String, Object>((int) (size / 0.75));
			for (int i = 0; i < size; i++) {
				int keySize = in.readInt();
				byte[] keyArray = new byte[keySize];
				in.readBytes(keyArray);
				String key = new String(keyArray, "UTF-8");
				attach.put(key, nettyMarshallingDecoder.decode(in));
			}
		}

		if (in.readableBytes() > 4) {
			message.setBody(nettyMarshallingDecoder.decode(in));
		}
		return message;
	}
}
